package com.cch.cooperation.api.zone.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cch.cooperation.api.auth.service.UserServiceImpl;
import com.cch.cooperation.api.zone.dto.ZoneUserDelDTO;
import com.cch.cooperation.api.zone.dto.ZoneUserUpdateDTO;
import com.cch.cooperation.biz.common.util.BeanUtilEx;
import com.cch.cooperation.common.exception.BizException;
import com.cch.cooperation.common.util.SnowflakeIdUtil;
import com.cch.cooperation.dao.auth.model.User;
import com.cch.cooperation.dao.zone.dto.ZoneUserDTO;
import com.cch.cooperation.dao.zone.enums.ZoneUserEnum;
import com.cch.cooperation.dao.zone.mapper.ZoneUserMapper;
import com.cch.cooperation.dao.zone.model.ZoneUser;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ZoneUserServiceImpl {

    @Resource
    private ZoneUserMapper mapper;
    @Resource
    private UserServiceImpl userService;

    public List<ZoneUserDTO> queryList(String zoneId) {
        if (StrUtil.isEmpty(zoneId)) {
            throw new BizException("空间id不能位空");
        }
        LambdaQueryWrapper<ZoneUser> query = new LambdaQueryWrapper<>();
        query.eq(ZoneUser::getZoneId, zoneId);
        List<ZoneUser> zoneUsers = mapper.selectList(query);
        return convertToDTO(zoneUsers.stream().map(ZoneUser::getId).distinct().collect(Collectors.toList()));
    }

    public Map<String, ZoneUserDTO> getMapByUserIds(String zoneId, List<String> userIds) {
        LambdaQueryWrapper<ZoneUser> query = new LambdaQueryWrapper<>();
        query.eq(ZoneUser::getZoneId, zoneId);
        query.in(ZoneUser::getUserId, userIds);
        List<ZoneUser> zoneUsers = mapper.selectList(query);
        List<ZoneUserDTO> result = convertToDTO(zoneUsers.stream().map(ZoneUser::getId).distinct().collect(Collectors.toList()));
        return result.stream().collect(Collectors.toMap(ZoneUserDTO::getId, o -> o, (o1, o2) -> o1));
    }

    public List<ZoneUserDTO> convertToDTO(List<String> ids) {
        if (CollUtil.isEmpty(ids)) {
            return new ArrayList<>();
        }
        List<ZoneUser> zoneUsers = mapper.selectBatchIds(ids);
        // 查询关联用户详情
        List<String> userIds = zoneUsers.stream().map(o -> o.getUserId()).distinct().collect(Collectors.toList());
        Map<String, User> userMap = userService.getMapByIds(userIds);
        // 聚合关联用户信息
        List<ZoneUserDTO> result = new ArrayList<>();
        for (ZoneUser item : zoneUsers) {
            User user = userMap.getOrDefault(item.getUserId(), new User());
            ZoneUserDTO zoneUser = BeanUtilEx.copy(user, ZoneUserDTO.class);
            zoneUser.setZoneNickname(StrUtil.isNotEmpty(item.getZoneNickname()) ? item.getZoneNickname() : user.getNickname());
            zoneUser.setRoleType(item.getRoleType());
            result.add(zoneUser);
        }
        return result;
    }

    public void add(String zoneId, String userId, Integer roleType) {
        ZoneUser zoneUser = new ZoneUser();
        zoneUser.setId(SnowflakeIdUtil.getIdStr());
        zoneUser.setZoneId(zoneId);
        zoneUser.setUserId(userId);
        zoneUser.setRoleType(roleType);
        zoneUser.setCreateTime(new Date());
        mapper.insert(zoneUser);
    }

    public ZoneUserDTO update(@Valid ZoneUserUpdateDTO req) {
        LambdaQueryWrapper<ZoneUser> query = new LambdaQueryWrapper<>();
        query.eq(ZoneUser::getZoneId, req.getZoneId());
        query.eq(ZoneUser::getUserId, req.getUserId());
        query.last("limit 1");
        ZoneUser zoneUser = mapper.selectOne(query);
        if (ObjectUtil.isNull(zoneUser)) {
            throw new BizException("该空间用户不存在");
        }
        zoneUser.setZoneNickname(req.getNickname());
        mapper.updateById(zoneUser);
        return queryList(req.getZoneId()).stream().filter(o -> o.getId().equals(req.getUserId())).findFirst().orElse(null);
    }

    public void delete(@Valid ZoneUserDelDTO req) {
        LambdaQueryWrapper<ZoneUser> query = new LambdaQueryWrapper<>();
        query.eq(ZoneUser::getZoneId, req.getZoneId());
        query.in(ZoneUser::getUserId, req.getUserIds());
        query.ne(ZoneUser::getRoleType, ZoneUserEnum.RoleType.ADMIN.value);
        mapper.delete(query);
    }

}
